////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

// Στο παρόν module έχουμε δομές και μεθόδους που εξυπηρετούν την αναζήτηση
// παικτών. Τα κριτήρια αναζήτησης αφορούν στο όνομα, την κατάσταση και τη
// σχετικότητα των παικτών. Πιο συγκεκριμένα, ο χρήστης μπορεί να δώσει μέρος,
// ή ολόκληρο το όνομα, να καθορίσει αν επιθυμεί παίκτες αναξαρτήτως κατάστασης,
// παίκτες διαθέσιμους για παιχνίδι, ή online παίκτες, ή παίκτες τους οποίους
// έχει εντάξει στους φίλους, ή έχει αποκλείσει.
//
// Οι αναζητήσεις που αφορούν σε online παίκτες, διαθέσιμους ή μη, εκτελούνται
// απευθείας στον client, επομένως οι υπηρεσίες του παρόντος module ζητούνται
// μόνο κατά τις αναζητήσεις ανεξαρτήτως κατάστασης και με κριτήρια το όνομα
// και τη σχετικότητα ή μη των αναζητουμένων παικτών.

Log.print('service module: anazitisi');

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

// Τα σχετικά με τις υπηρεσίες που ορίζονται στο παρόν module εντάσσονται στο
// singleton "anazitisi" το οποίο χρησιμοποιείται ως name space.

Service.anazitisi = {};

////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////////@

// Το πρώτο βήμα στην αναζήτηση των παικτών περιλαμβάνει τον έλεγχο του αιτούντος
// και την ανατομή των κριτηρίων.

Service.anazitisi.action = function(req) {
	if (req.isvoli()) return;

	// Αν έχει καθοριστεί μέρος του ονόματος αυτό έχει περαστεί μέσω
	// της παραμέτρου "onoma".

	if (!req.url.hasOwnProperty('onoma')) var onoma = '';
	else onoma = req.url.onoma.trim();

	// Η παράμετρος "sxetikos" είναι 1 ή 0 ανάλογα με το αν επιθυμούμε
	// μόνο σχετικούς ή όλους τους παίκτες αντίστοιχα.

	if (!req.url.hasOwnProperty('sxetikos')) var sxetikos = 0;
	else sxetikos = parseInt(req.url.sxetikos) ? 1 : 0;

	// Αν δεν έχουν καθοριστεί καθόλου κριτήρια επιστρέφουμε
	// αμέσως καθώς θα ήταν παράλογο να επιστρέψουμε όλους
	// τους εγγεγραμμένους παίκτες.

	if ((!onoma) && (!sxetikos)) return req.end();

	// Τα επιστρεφόμενα αποτελέσματα περικόπτονται σύμφωνα με το
	// όριο "anazitisiMax" το οποίο είναι γνωστό τόσο στον server,
	// όσο και στον client. Ο παρακάτω μετρητής θα καταμετρήσει τα
	// αποτελέσματα και μόλις φτάσει στο όριο θα διακόψει την
	// αναζήτηση.

	Service.anazitisi.count = 0;

	// Τα αποτελέσματα θα επιστραφούν ως json objects, ένα για κάθε
	// παίκτη, και θα ενταχθούν σε array από τον παραλήπτη client.

	req.header('json');

	// Η αναζήτηση εκκινεί με τους φίλους, προχωρεί στους ασχέτους,
	// και τελειώνει με τους αποκλεισμένους.

	var conn = DB.connection();
	Service.anazitisi.partida(conn, req, onoma, sxetikos, 'ΦΙΛΟΣ');
}

// Η function "partida" επιλέγει μια παρτίδα αναζητουμένων, ανάλογα με την
// παράμετρο "sxesi" που μπορεί να είναι: "ΦΙΛΟΣ", "ΑΠΚΛΕΙΣΜΕΝΟΣ", false.

Service.anazitisi.partida = function(conn, req, onoma, sxetikos, sxesi) {
	query = 'SELECT `login`, `onoma` FROM `pektis`';
	var sep = ' WHERE ';
	if (onoma) {
		var sonoma = conn.escape('%' + onoma + '%');
		query += sep + '((`login` LIKE ' + sonoma + ') OR (`onoma` LIKE ' + sonoma + '))';
		sep = ' AND ';
	}

	query += sep + '(`login` ';

	// Αν η παράμετρος "sxesi" είναι false, τότε επιλέγουμε τους ασχέτους,
	// αλλιώς επιλέγουμε αυτούς που έχουν τη συγκεκριμένη σχέση με τον
	// αιτούντα.

	query += sxesi ?
		'IN (SELECT `sxetizomenos` FROM `sxesi` WHERE (`pektis` = BINARY ' +
			conn.escape(req.pektis.login) + ') AND (`sxesi` = ' + conn.escape(sxesi) + '))'
	:
		'NOT IN (SELECT `sxetizomenos` FROM `sxesi` WHERE `pektis` = BINARY ' +
			conn.escape(req.pektis.login) + ')'
	;
	query += ') ORDER BY `login` LIMIT ' + Prefadoros.anazitisiMax;

	conn.query(query, function(conn, rows) {
		for (var i = 0; i < rows.length; i++) {
			var x = {
				l: rows[i]['login'],
				o: rows[i]['onoma'],
			};

			req.write((Service.anazitisi.count == 0 ? '' : ',') + globals.stringify(x));
			if (++Service.anazitisi.count < Prefadoros.anazitisiMax) continue;

			conn.free();
			req.end();
			return;
		}

		// Τα αποτελέσματα τής αναζήτησης επιστρέφονται σε τρεις παρτίδες: φίλοι, άσχετοι και
		// αποκλεισμένοι. Αυτό επιτυγχάνεται προγραμματιστικά με τρία αλυσιδωτά queries. Στο
		// σημείο αυτό έχει τελειώσει ένα από αυτά τα queries και είτε δρομολογούμε το επόμενο,
		// είτε κλείνουμε την απάντησή μας, εφόσον το τελευταίο query αφορούσε τους αποκλεισμένους.

		switch (sxesi) {
		case 'ΦΙΛΟΣ':
			Service.anazitisi.partida(conn, req, onoma, sxetikos, sxetikos ? 'ΑΠΟΚΛΕΙΣΜΕΝΟΣ' : false);
			break;
		case 'ΑΠΟΚΛΕΙΣΜΕΝΟΣ':
			conn.free();
			req.end();
			break;
		default:
			Service.anazitisi.partida(conn, req, onoma, sxetikos, 'ΑΠΟΚΛΕΙΣΜΕΝΟΣ');
			break;
		}
	});
}
